//
//  NumberMatrix.m
//  2048
//
//  Created by Training Camp on 11/11/14.
//  Copyright (c) 2014 TrainingCamp. All rights reserved.
//

#import "NumberMatrix.h"

@interface NumberMatrix ()

@property NSMutableArray* rows;

@end

static const NSInteger kDimensions = 4;

@implementation NumberMatrix

- (void) sumInDirection:(NSString*) direction{
    BOOL moveExists = NO;
    if ([direction isEqualToString:@"Left"] || [direction isEqualToString:@"Right"]) {
        if ([self sumRowsWithDirection:direction]){
            moveExists = YES;
        }
    }
    else if ([direction isEqualToString:@"Up"] || [direction isEqualToString:@"Down"]){
        if ([self sumColsWithDirection:direction]){
            moveExists = YES;
        }
    }
    if (moveExists){
        [self addRandom];
    }
}

- (BOOL) sumRowsWithDirection:(NSString *)direction{
    BOOL moveExists = NO;
    for (int i = 0; i < kDimensions; i++) {
        if ([self sumRow:i withDirection:direction]){
            moveExists = YES;
        }
    }
    return moveExists;
}

- (BOOL) sumColsWithDirection:(NSString *) direction{
    BOOL moveExists = NO;
    for (int i = 0; i < kDimensions; i++) {
        if ([self sumCol:i withDirection:direction]){
            moveExists = YES;
        }
    }
    return moveExists;
}

- (BOOL) sumRow:(NSInteger) rowIndex withDirection:(NSString*) direction{
    
    NSMutableArray* sum = [[NSMutableArray alloc] initWithCapacity:kDimensions];
    NSNumber* first; // = self.rows[index][0];
    NSNumber* next;  // = self.rows[index][1];
    
    NSInteger loopStart;
    NSInteger loopEnd;
    NSInteger loopIncrement;
    
    BOOL moveExists = NO;
    
    for (NSNumber* number in self.rows[rowIndex]){
        if (![number isEqualToNumber:@0]) {
            [sum addObject:number];
        }
    }
    if (sum != nil){
        
        if ([direction isEqualToString:@"Left"]) {
            loopStart = 0;
            loopEnd = 2;
            loopIncrement = 1;
        }
        else{
            loopStart = [sum count] - 1;
            loopEnd = -1;
            loopIncrement = -1;
        }        
        
        for (NSInteger col = loopStart; (int)col * loopIncrement <= (int)([sum count] * ([direction isEqualToString:@"Left"] ? 1:0) - loopEnd) * loopIncrement; col += loopIncrement) { // Don't ask...
            first = sum[col];
            next = sum[col+loopIncrement];
            if ([first isEqualToNumber:next]){
                sum[col] = [NSNumber numberWithInteger:[first integerValue] * 2];
                [sum removeObjectAtIndex:col+loopIncrement];
                moveExists = YES;
            }
        }
        // Adding empty cells
        while ([sum count] < kDimensions){
            if ([direction isEqual:@"Left"]) {
                [sum addObject:@0];
            }
            else{
                [sum insertObject:@0 atIndex:0];
            }
        }
        if (![self.rows[rowIndex] isEqual:sum]) {
            moveExists = YES;
        }
        self.rows[rowIndex] = sum;
        
    }
    return moveExists;
}

- (BOOL) sumCol:(NSInteger) colIndex withDirection:(NSString*) direction{
    
    NSMutableArray* sum = [[NSMutableArray alloc] initWithCapacity:kDimensions];
    NSNumber* first; // = self.rows[index][0];
    NSNumber* next;  // = self.rows[index][1];
    
    NSInteger loopStart;
    NSInteger loopEnd;
    NSInteger loopIncrement;
    
    BOOL moveExists = NO;
    
    for (NSArray* row in self.rows){
        if (![row[colIndex] isEqualToNumber:@0]) {
            [sum addObject:row[colIndex]];
        }
    }
    
    if (sum != nil){
        
        if ([direction isEqualToString:@"Up"]) {
            loopStart = 0;
            loopEnd = 2;
            loopIncrement = 1;
        }
        else{
            loopStart = [sum count] - 1;
            loopEnd = -1;
            loopIncrement = -1;
        }
        
        for (NSInteger row = loopStart; (int)row * loopIncrement <= (int)([sum count] * ([direction isEqualToString:@"Up"] ? 1:0) - loopEnd) * loopIncrement; row += loopIncrement) { // Don't ask...
            first = sum[row];
            next = sum[row+loopIncrement];
            if ([first isEqualToNumber:next]){
                sum[row] = [NSNumber numberWithInteger:[first integerValue] * 2];
                [sum removeObjectAtIndex:row+loopIncrement];
                moveExists = YES;
            }
        }
        // Adding empty cells
        while ([sum count] < kDimensions){
            if ([direction isEqual:@"Up"]) {
                [sum addObject:@0];
            }
            else{
                [sum insertObject:@0 atIndex:0];
            }
        }
        
        for (NSInteger rowIndex = 0; rowIndex < kDimensions; rowIndex++){
            
            NSMutableArray *newRow = [[NSMutableArray alloc] initWithCapacity:kDimensions];
            for (NSInteger col = 0; col < kDimensions; col++) {
                if (col == colIndex) {
                    [newRow addObject:sum[rowIndex]];
                    if (![sum[rowIndex] isEqual:self.rows[rowIndex][colIndex]]){
                        moveExists = YES;
                    }
                }
                else{
                    [newRow addObject:self.rows[rowIndex][col]];
                }
            }
            self.rows[rowIndex] = newRow;
        }
    }
    return moveExists;
}

- (void) printToConsole{
    NSLog(@"%@", self.rows);
}

- (void) addRandom{
    BOOL addedNumber = NO;
    while (!addedNumber) {
        NSInteger x = arc4random_uniform(4);
        NSInteger y = arc4random_uniform(4);
        if ([self.rows[x][y] isEqual:@0]) {
            NSNumber* number = [NSNumber numberWithInteger:((arc4random_uniform(2) + 1) * 2)];
            self.rows[x][y] = number;
            addedNumber = YES;
        }
        
    }
    
}

- (NSArray*) output{
    return [NSArray arrayWithArray:self.rows];
}




- (instancetype)init
{
    self = [super init];
    if (self) {
        self.rows =[[NSMutableArray alloc] initWithCapacity:kDimensions];
        for (int i = 0; i< kDimensions; i++) {
            self.rows[i] = [[NSMutableArray alloc] initWithCapacity:kDimensions];
        }
        for (int i = 0; i < kDimensions; i++) {
            for(int j = 0; j < kDimensions; j++) {
                self.rows[i][j] = @0;
            }
        }
        [self addRandom];
        [self addRandom];
    }
    return self;
}



@end
